package com.example.maze;

import java.util.ArrayList;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class MazeActivity extends Activity implements OnClickListener{

	//displays how many moves a user has made
	private TextView countMoves;
	//to store total moves
	private int storeNumberMoves;
	//displays end point
	private TextView endPoint;
	//the button the user presses to go forward
	private Button upButton;
	//the button the user presses to go left
	private Button leftButton;
	//the button the user presses to go right
	private Button rightButton;
	//the button the user presses to go back
	private Button downButton;
	//builds the maze
	private Maze maze;
	private TextView movesText;
	//displaying a list of moves and dialog
	private ListView listMoves;
	private ArrayList<String> moveListData;
	private ArrayAdapter<String> adapter;
	//every second it starts a thread
	private Handler customHandler = new Handler();
	//fields for the player's choices
	private int timeCounter;
	private GameMode gameMode;
	private int size;
	private int percent;
	private String edit;
	//creating the keys for storing the data later
	public static final String NAME_KEY = "name";
	public static final String MOVES_KEY = "moves";
	public static final String TIME_KEY = "time";
	public static final String SIZE_KEY = "size";
	public static final String PERCENT_KEY = "percent";
	public static final String TYPE_KEY = "type";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.maze_activity);
		//gets the different views
		countMoves = (TextView) findViewById(R.id.score);
		endPoint = (TextView) findViewById(R.id.endPoint);
		upButton = (Button) findViewById(R.id.upButton);
		leftButton = (Button) findViewById(R.id.leftButton);
		rightButton = (Button) findViewById(R.id.rightButton);
		downButton = (Button) findViewById(R.id.downButton);
		listMoves = (ListView) findViewById(R.id.listMoves);
		movesText = (TextView) findViewById(R.id.movesText);
		//making this class the onClickListener for these buttons
		upButton.setOnClickListener(this);
		leftButton.setOnClickListener(this);
		rightButton.setOnClickListener(this);
		downButton.setOnClickListener(this);
		
		if(savedInstanceState != null){
			//getting the saved state of the game in case of screen rotation 
			//or navigating away from the game
			size = savedInstanceState.getInt("size");
			percent = savedInstanceState.getInt("percent");
			maze = (Maze) savedInstanceState.getParcelable("maze");
			moveListData = savedInstanceState.getStringArrayList("moveList");
			gameMode = GameMode.values()[savedInstanceState.getInt("gameMode")];
			if(GameMode.Moves == gameMode){
				storeNumberMoves = savedInstanceState.getInt("moves");
			}else{
				timeCounter = savedInstanceState.getInt("timeCounter");
			}
			edit = MyDialogFragment.NAME_KEY;
			String endText = positionText(maze.getEndPosition());
			endPoint.setText(endText);
		}else{
			//the first instance of the game
			//getting the values from the intent in the start up activity
			size = getIntent().getIntExtra(StartUpActivity.STORE_SIZE_KEY, 4);
			percent = getIntent().getIntExtra(StartUpActivity.STORE_PERCENT_KEY, 10);
			gameMode = GameMode.values()[getIntent().getIntExtra(StartUpActivity.MODE_ORDINAL_KEY, 0)];
			//generates maze with coordinates
			maze = MazeGenerator.generate(size, percent);
			storeNumberMoves = 0;
			//takes position and turns it into string
			String endText = positionText(maze.getEndPosition());
			endPoint.setText(endText);
			//adding the starting text
			moveListData = new ArrayList<String>();
			moveListData.add(0, "Welcome! Your starting point is " + positionText(maze.getCurrentPosition()));
			moveListData.add(0, "Your goal is to reach " + endText);
			timeCounter = 0;
		}
		
		if(GameMode.Moves == gameMode){
			countMoves.setText(String.valueOf(storeNumberMoves));
		}
		//making the time display properly for the player
		else if(GameMode.Timed == gameMode){
			customHandler.postDelayed(updateTimerThread, 1000);
			movesText.setText("");
			int mins = timeCounter / 60;
			int secs = timeCounter % 60;
			countMoves.setText("" + mins + ":"
					+ String.format("%02d", secs));
		}
		//pre-built layout for how each individual item should look
				adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, moveListData);
				listMoves.setAdapter(adapter);
	}
	//uses interface runnable
	private Runnable updateTimerThread = new Runnable() {

		public void run() {
			if(!maze.isItTheEnd()){
				//adds to the time counter 
				timeCounter++;
				//sets the text
				int mins = timeCounter / 60;
				int secs = timeCounter % 60;
				countMoves.setText("" + mins + ":"
						+ String.format("%02d", secs));
				//sets off the next 1000 milliseconds
				customHandler.postDelayed(this, 1000);
			}
		}
	};
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		//saving the game data if screen is turned etc
		outState.putParcelable("maze", maze);
		outState.putInt("moves", storeNumberMoves);
		outState.putInt("size", size);
		outState.putInt("percent", percent);
		outState.putStringArrayList("moveList", moveListData);
		outState.putInt("gameMode",gameMode.ordinal());
		outState.putInt("timeCounter", timeCounter);
		outState.putString("name", edit);
		super.onSaveInstanceState(outState);
	}
	//making the position into a string
	private String positionText(Position position) {
		int x = position.getX();
		int y = position.getY();
		return "(" + x + ", " + y + ")";
	}

	@Override
	public void onClick(View view) {
		//what happens when a button is clicked and notifying adapter etc
		Direction direction = null;
		if(upButton == view){
			direction = Direction.Up;
		}
		
		else if(leftButton == view) {
			direction = Direction.Left;
		}
		
		else if(rightButton == view){
			direction = Direction.Right;
		}
		
		else if(downButton == view){
			direction = Direction.Down;
		}
		++storeNumberMoves;
		if(GameMode.Moves == gameMode){
			countMoves.setText(String.valueOf(storeNumberMoves));
		
		}
		String moveAcknowledged = "You pressed "+direction.toString().toLowerCase()+"!";
		//adding the string to the data at the top of the list
		moveListData.add(0, moveAcknowledged);
		adapter.notifyDataSetChanged();
		if(maze.isMovePossible(direction)){
			//check if the move is possible
			maze.move(direction);
			//check if the move is the end point
			if(maze.isItTheEnd()){
				
				MyDialogFragment myDialogFragment = new MyDialogFragment();
				Bundle args = new Bundle();
			    args.putInt(MOVES_KEY, storeNumberMoves);
			    args.putInt(TIME_KEY, timeCounter);
			    args.putInt(SIZE_KEY, size);
			    args.putInt(PERCENT_KEY, percent);
			    args.putInt(TYPE_KEY, gameMode.ordinal());
			    myDialogFragment.setArguments(args);
		        myDialogFragment.show(getFragmentManager(), "tag");
	
			}else{
				//telling player where they are
				String informPosition = "You went "+direction.toString().toLowerCase()+"! Your new position is " + positionText(maze.getCurrentPosition());
				moveListData.add(0, informPosition);
				adapter.notifyDataSetChanged();
			}
		}else{
			//telling player they cannot go through the wall
			String informPosition = "You found a wall, you cannot go "+direction.toString().toLowerCase()+"!";
			moveListData.add(0, informPosition);
			adapter.notifyDataSetChanged();
		}
	}
}
